#include "stdafx.h"

//*****************************************************************************
int initUMaterialProperty(material *substance) 
{
	int k;
	//u
	k = 0;
	substance[k].id = 0; 
	sprintf(substance[k].name, "u - 22MnB5 Steel");
	substance[k].density = 7830;			//UNIT:kg/m^3
	substance[k].htc = 32;					//UNIT:W/(m*K)
	substance[k].sh = 650;					//UNIT:J/(kg*K)
	substance[k].initTemp = PLATE_INIT_TEMP;//UNIT:K

	//Die Up
	k = 1;
	substance[k].id = 1;
	sprintf(substance[k].name, "Die Up - 5CrMnMo Steel");
	substance[k].density = 7500;
	substance[k].htc = 35.23;
	substance[k].sh = 678.5;
	substance[k].initTemp = AIR_INIT_TEMP;

	//Die Down
	k = 2;
	substance[k].id = 2;
	sprintf(substance[k].name, "Die Down - HT200 - w(C) = 3%");
	substance[k].density = 7570;
	substance[k].htc = 39.2;
	substance[k].sh = 470;
	substance[k].initTemp = AIR_INIT_TEMP;

	//Gas
	k = 3;
	substance[k].id = 3;
	sprintf(substance[k].name, "Gas - Air");
	substance[k].density = 1.205;
	substance[k].htc = 0.0259;
	substance[k].sh = 1005;
	substance[k].initTemp = AIR_INIT_TEMP;

	substance[0].both[0] = 0; substance[1].both[0] = 0; substance[2].both[0] = 0; substance[3].both[0] = 20000;
	substance[0].both[1] = 0; substance[1].both[1] = 0; substance[2].both[1] = 0; substance[3].both[1] = 20000;
	substance[0].both[2] = 0; substance[1].both[2] = 0; substance[2].both[2] = 0; substance[3].both[2] = 20000;
	substance[0].both[3] = 20000; substance[1].both[3] = 20000; substance[2].both[3] = 20000; substance[3].both[3] = 0;

	return 1;
}

//*****************************************************************************
int initUHtcInter(material *substance, double dx, 
				  double htcInter[NUM_MATERIAL][NUM_MATERIAL]) 
{
	double r, k;
	for(int i = 0; i < NUM_MATERIAL; i++)
		for(int j = i; j < NUM_MATERIAL; j++)
		{
			if (substance[i].both[j] == 0) 
				r = 0; 
			else 
				r = 1 / substance[i].both[j];
			if (i == 0 && (j == 1 || j == 2)) 
				k = TOUCH_FACTOR; 
			else 
				k = 1;
			htcInter[i][j] = htcInter[j][i] = k * dx / 
				(r + dx / 2 / substance[i].htc + dx / 2 / substance[j].htc);
			if (i == 0 && (j == 1 || j == 2)) 
				htcInter[i][j] = htcInter[j][i] = 7;
		}

	return 1;
}

//*****************************************************************************
int initUBlock(int up, int down, int left, int right, int id, int **grid)
{
	for(int i = up; i < down; i++)
		for(int j = left; j < right; j++)
			grid[i][j] = id;

	return 1;
}

int initUUpRadius(int up, int left, int r, int id, int **grid)
{
	for (int i = 0; i < r; i++)
		for(int j = sqrt((double)(2 * r * i - i * i)) + 1; j < r; j++)
			grid[up + i][left + j] = id;
	return 1;
}

int initUDownRadius(int up, int left, int r, int id, int **grid)
{
	for (int i = 0; i < r; i++)
		for(int j = 0; j < r - sqrt((double)(r * r - i * i)); j++)
			grid[up + i][left + j] = id;
	return 1;
}

//*****************************************************************************
//init u 2D
int** u2DInit(material *substance, double htcInter[NUM_MATERIAL][NUM_MATERIAL], 
			  double *dx, int *row, int *col,
			  double *tempEdge, terminationCondition2D *tc)
{
	//substance
	initUMaterialProperty(substance);
	//dx
	*dx = 0.0001;
	//htcInter
	initUHtcInter(substance, *dx, htcInter);
	//row + col
	double	uHeight				= 0.0265;
	double	uWidth				= 0.090;
	double	uHollow				= 0.030;
	double	uUpRadius			= 0.0075;
	double	uDownRadius			= 0.0045;
	double	uThickness			= 0.0015;

	double	uDieUpHeight		= 0.030;
	double	uDieUpWidth			= 0.100;
	double	uDieDownHeight		= 0.045;
	double	uDieDownWidtth		= 0.1200;
	double	airThick			= 0.002;

	int		uHeightNum			= uHeight / *dx;
	int		uWidthNum			= uWidth / *dx;
	int		uHollowNum			= uHollow / *dx;
	int		uUpRadiusNum		= uUpRadius / *dx;
	int		uDownRadiusNum		= uDownRadius / *dx;
	int		uThicknessNum		= uThickness / *dx;

	int		uDieUpHeightNum		= uDieUpHeight / *dx;
	int		uDieUpWidthNum		= uDieUpWidth / *dx;
	int		uDieDownHeightNum	= uDieDownHeight / *dx;
	int		uDieDownWidthNum	= uDieDownWidtth / *dx;
	int		airThickNum			= airThick / *dx;

	*row = airThickNum + uDieUpHeightNum + uThicknessNum + uDieDownHeightNum +  airThickNum;
	*col = airThickNum + (uDieUpWidthNum > uDieDownWidthNum ? uDieUpWidthNum : uDieDownWidthNum) + airThickNum;
	//grid
	int **grid = (int **)malloc(sizeof(int *) * (*row));
	for(int i = 0; i < *row; i++) grid[i] = (int *)malloc(sizeof(int) * (*col));

	int up, down, left, right, k;
	//init block - Gas - Air
	k = 3;
	up = 0; down = *row; left = 0; right = *col / 2; 
	initUBlock(up, down, left, right, substance[k].id, grid);
	//init block - Die Up -  
	k = 1;
	up = airThickNum; down = up + uDieUpHeightNum; 
	left = (*col - uDieUpWidthNum) / 2; right = *col / 2;
	initUBlock(up, down, left, right, substance[k].id, grid);
	//init block - Die Down - 
	k = 2;
	up = airThickNum + uDieUpHeightNum + uThicknessNum; down = up + uDieDownHeightNum; 
	left = (*col -  uDieDownWidthNum) / 2; right = *col / 2; 
	initUBlock(up, down, left, right, substance[k].id, grid);
	//init block - u - 
	k = 0;
	up = airThickNum + uDieUpHeightNum; down = up + uHeightNum; 
	left = (*col - uWidthNum) / 2; right = *col / 2; 
	initUBlock(up, down, left, right, substance[k].id, grid);
	k = 2;
	up = airThickNum + uDieUpHeightNum + uThicknessNum; down = up + uHeightNum - uThicknessNum; 
	left = (*col - uWidthNum) / 2; right = *col / 2 - uHollowNum / 2 - uThicknessNum; 
	initUBlock(up, down, left, right, substance[k].id, grid);
	//bulge
	k = 1;
	up = airThickNum + uDieUpHeightNum; down = up + uHeightNum - uThicknessNum; 
	left = *col / 2 - uHollowNum / 2; right = *col / 2; 
	initUBlock(up, down, left, right, substance[k].id, grid);
	//uUpRadius
	int r;
	k = 0; r = uUpRadiusNum - uThicknessNum; 
	up = airThickNum + uDieUpHeightNum + uThicknessNum; 
	left = *col / 2 - uHollowNum / 2 - uUpRadiusNum;
	initUUpRadius(up, left, r, substance[k].id, grid);
	k = 1; r = uUpRadiusNum; 
	up = airThickNum + uDieUpHeightNum; 
	left = *col / 2 - uHollowNum / 2 - uUpRadiusNum;
	initUUpRadius(up, left, r, substance[k].id, grid);
	//uDownRadius
	k = 0; r = uDownRadiusNum; 
	up = airThickNum + uDieUpHeightNum + uHeightNum - uThicknessNum - uDownRadiusNum; 
	left = *col / 2 - uHollowNum / 2;
	initUDownRadius(up, left, r, substance[k].id, grid);
	k = 2; r = uDownRadiusNum + uThicknessNum; 
	up = airThickNum + uDieUpHeightNum + uHeightNum - uThicknessNum - uDownRadiusNum; 
	left = *col / 2 - uHollowNum / 2 - uThicknessNum;
	initUDownRadius(up, left, r, substance[k].id, grid);

	for(int i = 0; i < *row; i++)
		for(int j = *col / 2; j < *col; j++)
			grid[i][j] = grid[i][*col - 1 - j];

	////edge
	//for(int i = 0; i < *row; i++)
	//	grid[i][0] = grid[i][*col - 1] = EDGE_ID;
	//for(int i = 0; i < *col; i++)
	//	grid[0][i] = grid[*row - 1][i] = EDGE_ID;

	//tempEdge
	*tempEdge = substance[3].initTemp;

	//tc
	(*tc).x = *col / 2;
	(*tc).y = airThickNum + uDieUpHeightNum + uHeightNum - uThicknessNum / 2;
	(*tc).terminationTemp = TERMINATION_TEMPERATION;

	return grid;
}